//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

@_exported import SotoCore

/// Service object for interacting with AWS SSMIncidents service.
///
/// Systems Manager Incident Manager is an incident management console designed to help users mitigate and recover from incidents affecting their Amazon Web Services-hosted applications. An incident is any unplanned interruption or reduction in quality of services.  Incident Manager increases incident resolution by notifying responders of impact, highlighting relevant troubleshooting data, and providing collaboration tools to get services back up and running. To achieve the primary goal of reducing the time-to-resolution of critical incidents, Incident Manager automates response plans and enables responder team escalation.
public struct SSMIncidents: AWSService {
    // MARK: Member variables

    /// Client used for communication with AWS
    public let client: AWSClient
    /// Service configuration
    public let config: AWSServiceConfig

    // MARK: Initialization

    /// Initialize the SSMIncidents client
    /// - parameters:
    ///     - client: AWSClient used to process requests
    ///     - region: Region of server you want to communicate with. This will override the partition parameter.
    ///     - partition: AWS partition where service resides, standard (.aws), china (.awscn), government (.awsusgov).
    ///     - endpoint: Custom endpoint URL to use instead of standard AWS servers
    ///     - timeout: Timeout value for HTTP requests
    public init(
        client: AWSClient,
        region: SotoCore.Region? = nil,
        partition: AWSPartition = .aws,
        endpoint: String? = nil,
        timeout: TimeAmount? = nil,
        byteBufferAllocator: ByteBufferAllocator = ByteBufferAllocator(),
        options: AWSServiceConfig.Options = []
    ) {
        self.client = client
        self.config = AWSServiceConfig(
            region: region,
            partition: region?.partition ?? partition,
            service: "ssm-incidents",
            serviceProtocol: .restjson,
            apiVersion: "2018-05-10",
            endpoint: endpoint,
            errorType: SSMIncidentsErrorType.self,
            timeout: timeout,
            byteBufferAllocator: byteBufferAllocator,
            options: options
        )
    }

    // MARK: API Calls

    /// A replication set replicates and encrypts your data to the provided Regions with the provided KMS key.
    public func createReplicationSet(_ input: CreateReplicationSetInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<CreateReplicationSetOutput> {
        return self.client.execute(operation: "CreateReplicationSet", path: "/createReplicationSet", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Creates a response plan that automates the initial response to incidents. A response plan engages contacts, starts chat channel collaboration, and initiates runbooks at the beginning of an incident.
    public func createResponsePlan(_ input: CreateResponsePlanInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<CreateResponsePlanOutput> {
        return self.client.execute(operation: "CreateResponsePlan", path: "/createResponsePlan", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Creates a custom timeline event on the incident details page of an incident record. Timeline events are automatically created by Incident Manager, marking key moment during an incident. You can create custom timeline events to mark important events that are automatically detected by Incident Manager.
    public func createTimelineEvent(_ input: CreateTimelineEventInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<CreateTimelineEventOutput> {
        return self.client.execute(operation: "CreateTimelineEvent", path: "/createTimelineEvent", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Delete an incident record from Incident Manager.
    public func deleteIncidentRecord(_ input: DeleteIncidentRecordInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<DeleteIncidentRecordOutput> {
        return self.client.execute(operation: "DeleteIncidentRecord", path: "/deleteIncidentRecord", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Deletes all Regions in your replication set. Deleting the replication set deletes all Incident Manager data.
    public func deleteReplicationSet(_ input: DeleteReplicationSetInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<DeleteReplicationSetOutput> {
        return self.client.execute(operation: "DeleteReplicationSet", path: "/deleteReplicationSet", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Deletes the resource policy that Resource Access Manager uses to share your Incident Manager resource.
    public func deleteResourcePolicy(_ input: DeleteResourcePolicyInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<DeleteResourcePolicyOutput> {
        return self.client.execute(operation: "DeleteResourcePolicy", path: "/deleteResourcePolicy", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Deletes the specified response plan. Deleting a response plan stops all linked CloudWatch alarms and EventBridge events from creating an incident with this response plan.
    public func deleteResponsePlan(_ input: DeleteResponsePlanInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<DeleteResponsePlanOutput> {
        return self.client.execute(operation: "DeleteResponsePlan", path: "/deleteResponsePlan", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Deletes a timeline event from an incident.
    public func deleteTimelineEvent(_ input: DeleteTimelineEventInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<DeleteTimelineEventOutput> {
        return self.client.execute(operation: "DeleteTimelineEvent", path: "/deleteTimelineEvent", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Returns the details for the specified incident record.
    public func getIncidentRecord(_ input: GetIncidentRecordInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<GetIncidentRecordOutput> {
        return self.client.execute(operation: "GetIncidentRecord", path: "/getIncidentRecord", httpMethod: .GET, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Retrieve your Incident Manager replication set.
    public func getReplicationSet(_ input: GetReplicationSetInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<GetReplicationSetOutput> {
        return self.client.execute(operation: "GetReplicationSet", path: "/getReplicationSet", httpMethod: .GET, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Retrieves the resource policies attached to the specified response plan.
    public func getResourcePolicies(_ input: GetResourcePoliciesInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<GetResourcePoliciesOutput> {
        return self.client.execute(operation: "GetResourcePolicies", path: "/getResourcePolicies", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Retrieves the details of the specified response plan.
    public func getResponsePlan(_ input: GetResponsePlanInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<GetResponsePlanOutput> {
        return self.client.execute(operation: "GetResponsePlan", path: "/getResponsePlan", httpMethod: .GET, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Retrieves a timeline event based on its ID and incident record.
    public func getTimelineEvent(_ input: GetTimelineEventInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<GetTimelineEventOutput> {
        return self.client.execute(operation: "GetTimelineEvent", path: "/getTimelineEvent", httpMethod: .GET, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Lists all incident records in your account. Use this command to retrieve the Amazon Resource Name (ARN) of the incident record you want to update.
    public func listIncidentRecords(_ input: ListIncidentRecordsInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<ListIncidentRecordsOutput> {
        return self.client.execute(operation: "ListIncidentRecords", path: "/listIncidentRecords", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// List all related items for an incident record.
    public func listRelatedItems(_ input: ListRelatedItemsInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<ListRelatedItemsOutput> {
        return self.client.execute(operation: "ListRelatedItems", path: "/listRelatedItems", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Lists details about the replication set configured in your account.
    public func listReplicationSets(_ input: ListReplicationSetsInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<ListReplicationSetsOutput> {
        return self.client.execute(operation: "ListReplicationSets", path: "/listReplicationSets", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Lists all response plans in your account.
    public func listResponsePlans(_ input: ListResponsePlansInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<ListResponsePlansOutput> {
        return self.client.execute(operation: "ListResponsePlans", path: "/listResponsePlans", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Lists the tags that are attached to the specified response plan.
    public func listTagsForResource(_ input: ListTagsForResourceRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<ListTagsForResourceResponse> {
        return self.client.execute(operation: "ListTagsForResource", path: "/tags/{resourceArn}", httpMethod: .GET, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Lists timeline events for the specified incident record.
    public func listTimelineEvents(_ input: ListTimelineEventsInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<ListTimelineEventsOutput> {
        return self.client.execute(operation: "ListTimelineEvents", path: "/listTimelineEvents", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Adds a resource policy to the specified response plan. The resource policy is used to share the response plan using Resource Access Manager (RAM). For more information about cross-account sharing, see Cross-Region and cross-account incident management.
    public func putResourcePolicy(_ input: PutResourcePolicyInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<PutResourcePolicyOutput> {
        return self.client.execute(operation: "PutResourcePolicy", path: "/putResourcePolicy", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Used to start an incident from CloudWatch alarms, EventBridge events, or manually.
    public func startIncident(_ input: StartIncidentInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<StartIncidentOutput> {
        return self.client.execute(operation: "StartIncident", path: "/startIncident", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Adds a tag to a response plan.
    public func tagResource(_ input: TagResourceRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<TagResourceResponse> {
        return self.client.execute(operation: "TagResource", path: "/tags/{resourceArn}", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Removes a tag from a resource.
    public func untagResource(_ input: UntagResourceRequest, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<UntagResourceResponse> {
        return self.client.execute(operation: "UntagResource", path: "/tags/{resourceArn}", httpMethod: .DELETE, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Update deletion protection to either allow or deny deletion of the final Region in a replication set.
    public func updateDeletionProtection(_ input: UpdateDeletionProtectionInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<UpdateDeletionProtectionOutput> {
        return self.client.execute(operation: "UpdateDeletionProtection", path: "/updateDeletionProtection", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Update the details of an incident record. You can use this operation to update an incident record from the defined chat channel. For more information about using actions in chat channels, see Interacting through chat.
    public func updateIncidentRecord(_ input: UpdateIncidentRecordInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<UpdateIncidentRecordOutput> {
        return self.client.execute(operation: "UpdateIncidentRecord", path: "/updateIncidentRecord", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Add or remove related items from the related items tab of an incident record.
    public func updateRelatedItems(_ input: UpdateRelatedItemsInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<UpdateRelatedItemsOutput> {
        return self.client.execute(operation: "UpdateRelatedItems", path: "/updateRelatedItems", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Add or delete Regions from your replication set.
    public func updateReplicationSet(_ input: UpdateReplicationSetInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<UpdateReplicationSetOutput> {
        return self.client.execute(operation: "UpdateReplicationSet", path: "/updateReplicationSet", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Updates the specified response plan.
    public func updateResponsePlan(_ input: UpdateResponsePlanInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<UpdateResponsePlanOutput> {
        return self.client.execute(operation: "UpdateResponsePlan", path: "/updateResponsePlan", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }

    /// Updates a timeline event. You can update events of type Custom Event.
    public func updateTimelineEvent(_ input: UpdateTimelineEventInput, logger: Logger = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) -> EventLoopFuture<UpdateTimelineEventOutput> {
        return self.client.execute(operation: "UpdateTimelineEvent", path: "/updateTimelineEvent", httpMethod: .POST, serviceConfig: self.config, input: input, logger: logger, on: eventLoop)
    }
}

extension SSMIncidents {
    /// Initializer required by `AWSService.with(middlewares:timeout:byteBufferAllocator:options)`. You are not able to use this initializer directly as there are no public
    /// initializers for `AWSServiceConfig.Patch`. Please use `AWSService.with(middlewares:timeout:byteBufferAllocator:options)` instead.
    public init(from: SSMIncidents, patch: AWSServiceConfig.Patch) {
        self.client = from.client
        self.config = from.config.with(patch: patch)
    }
}

// MARK: Paginators

extension SSMIncidents {
    ///  Retrieves the resource policies attached to the specified response plan.
    ///
    /// Provide paginated results to closure `onPage` for it to combine them into one result.
    /// This works in a similar manner to `Array.reduce<Result>(_:_:) -> Result`.
    ///
    /// Parameters:
    ///   - input: Input for request
    ///   - initialValue: The value to use as the initial accumulating value. `initialValue` is passed to `onPage` the first time it is called.
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each paginated response. It combines an accumulating result with the contents of response. This combined result is then returned
    ///         along with a boolean indicating if the paginate operation should continue.
    public func getResourcePoliciesPaginator<Result>(
        _ input: GetResourcePoliciesInput,
        _ initialValue: Result,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (Result, GetResourcePoliciesOutput, EventLoop) -> EventLoopFuture<(Bool, Result)>
    ) -> EventLoopFuture<Result> {
        return self.client.paginate(
            input: input,
            initialValue: initialValue,
            command: self.getResourcePolicies,
            inputKey: \GetResourcePoliciesInput.nextToken,
            outputKey: \GetResourcePoliciesOutput.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    /// Provide paginated results to closure `onPage`.
    ///
    /// - Parameters:
    ///   - input: Input for request
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each block of entries. Returns boolean indicating whether we should continue.
    public func getResourcePoliciesPaginator(
        _ input: GetResourcePoliciesInput,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (GetResourcePoliciesOutput, EventLoop) -> EventLoopFuture<Bool>
    ) -> EventLoopFuture<Void> {
        return self.client.paginate(
            input: input,
            command: self.getResourcePolicies,
            inputKey: \GetResourcePoliciesInput.nextToken,
            outputKey: \GetResourcePoliciesOutput.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    ///  Lists all incident records in your account. Use this command to retrieve the Amazon Resource Name (ARN) of the incident record you want to update.
    ///
    /// Provide paginated results to closure `onPage` for it to combine them into one result.
    /// This works in a similar manner to `Array.reduce<Result>(_:_:) -> Result`.
    ///
    /// Parameters:
    ///   - input: Input for request
    ///   - initialValue: The value to use as the initial accumulating value. `initialValue` is passed to `onPage` the first time it is called.
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each paginated response. It combines an accumulating result with the contents of response. This combined result is then returned
    ///         along with a boolean indicating if the paginate operation should continue.
    public func listIncidentRecordsPaginator<Result>(
        _ input: ListIncidentRecordsInput,
        _ initialValue: Result,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (Result, ListIncidentRecordsOutput, EventLoop) -> EventLoopFuture<(Bool, Result)>
    ) -> EventLoopFuture<Result> {
        return self.client.paginate(
            input: input,
            initialValue: initialValue,
            command: self.listIncidentRecords,
            inputKey: \ListIncidentRecordsInput.nextToken,
            outputKey: \ListIncidentRecordsOutput.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    /// Provide paginated results to closure `onPage`.
    ///
    /// - Parameters:
    ///   - input: Input for request
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each block of entries. Returns boolean indicating whether we should continue.
    public func listIncidentRecordsPaginator(
        _ input: ListIncidentRecordsInput,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (ListIncidentRecordsOutput, EventLoop) -> EventLoopFuture<Bool>
    ) -> EventLoopFuture<Void> {
        return self.client.paginate(
            input: input,
            command: self.listIncidentRecords,
            inputKey: \ListIncidentRecordsInput.nextToken,
            outputKey: \ListIncidentRecordsOutput.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    ///  List all related items for an incident record.
    ///
    /// Provide paginated results to closure `onPage` for it to combine them into one result.
    /// This works in a similar manner to `Array.reduce<Result>(_:_:) -> Result`.
    ///
    /// Parameters:
    ///   - input: Input for request
    ///   - initialValue: The value to use as the initial accumulating value. `initialValue` is passed to `onPage` the first time it is called.
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each paginated response. It combines an accumulating result with the contents of response. This combined result is then returned
    ///         along with a boolean indicating if the paginate operation should continue.
    public func listRelatedItemsPaginator<Result>(
        _ input: ListRelatedItemsInput,
        _ initialValue: Result,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (Result, ListRelatedItemsOutput, EventLoop) -> EventLoopFuture<(Bool, Result)>
    ) -> EventLoopFuture<Result> {
        return self.client.paginate(
            input: input,
            initialValue: initialValue,
            command: self.listRelatedItems,
            inputKey: \ListRelatedItemsInput.nextToken,
            outputKey: \ListRelatedItemsOutput.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    /// Provide paginated results to closure `onPage`.
    ///
    /// - Parameters:
    ///   - input: Input for request
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each block of entries. Returns boolean indicating whether we should continue.
    public func listRelatedItemsPaginator(
        _ input: ListRelatedItemsInput,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (ListRelatedItemsOutput, EventLoop) -> EventLoopFuture<Bool>
    ) -> EventLoopFuture<Void> {
        return self.client.paginate(
            input: input,
            command: self.listRelatedItems,
            inputKey: \ListRelatedItemsInput.nextToken,
            outputKey: \ListRelatedItemsOutput.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    ///  Lists details about the replication set configured in your account.
    ///
    /// Provide paginated results to closure `onPage` for it to combine them into one result.
    /// This works in a similar manner to `Array.reduce<Result>(_:_:) -> Result`.
    ///
    /// Parameters:
    ///   - input: Input for request
    ///   - initialValue: The value to use as the initial accumulating value. `initialValue` is passed to `onPage` the first time it is called.
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each paginated response. It combines an accumulating result with the contents of response. This combined result is then returned
    ///         along with a boolean indicating if the paginate operation should continue.
    public func listReplicationSetsPaginator<Result>(
        _ input: ListReplicationSetsInput,
        _ initialValue: Result,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (Result, ListReplicationSetsOutput, EventLoop) -> EventLoopFuture<(Bool, Result)>
    ) -> EventLoopFuture<Result> {
        return self.client.paginate(
            input: input,
            initialValue: initialValue,
            command: self.listReplicationSets,
            inputKey: \ListReplicationSetsInput.nextToken,
            outputKey: \ListReplicationSetsOutput.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    /// Provide paginated results to closure `onPage`.
    ///
    /// - Parameters:
    ///   - input: Input for request
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each block of entries. Returns boolean indicating whether we should continue.
    public func listReplicationSetsPaginator(
        _ input: ListReplicationSetsInput,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (ListReplicationSetsOutput, EventLoop) -> EventLoopFuture<Bool>
    ) -> EventLoopFuture<Void> {
        return self.client.paginate(
            input: input,
            command: self.listReplicationSets,
            inputKey: \ListReplicationSetsInput.nextToken,
            outputKey: \ListReplicationSetsOutput.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    ///  Lists all response plans in your account.
    ///
    /// Provide paginated results to closure `onPage` for it to combine them into one result.
    /// This works in a similar manner to `Array.reduce<Result>(_:_:) -> Result`.
    ///
    /// Parameters:
    ///   - input: Input for request
    ///   - initialValue: The value to use as the initial accumulating value. `initialValue` is passed to `onPage` the first time it is called.
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each paginated response. It combines an accumulating result with the contents of response. This combined result is then returned
    ///         along with a boolean indicating if the paginate operation should continue.
    public func listResponsePlansPaginator<Result>(
        _ input: ListResponsePlansInput,
        _ initialValue: Result,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (Result, ListResponsePlansOutput, EventLoop) -> EventLoopFuture<(Bool, Result)>
    ) -> EventLoopFuture<Result> {
        return self.client.paginate(
            input: input,
            initialValue: initialValue,
            command: self.listResponsePlans,
            inputKey: \ListResponsePlansInput.nextToken,
            outputKey: \ListResponsePlansOutput.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    /// Provide paginated results to closure `onPage`.
    ///
    /// - Parameters:
    ///   - input: Input for request
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each block of entries. Returns boolean indicating whether we should continue.
    public func listResponsePlansPaginator(
        _ input: ListResponsePlansInput,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (ListResponsePlansOutput, EventLoop) -> EventLoopFuture<Bool>
    ) -> EventLoopFuture<Void> {
        return self.client.paginate(
            input: input,
            command: self.listResponsePlans,
            inputKey: \ListResponsePlansInput.nextToken,
            outputKey: \ListResponsePlansOutput.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    ///  Lists timeline events for the specified incident record.
    ///
    /// Provide paginated results to closure `onPage` for it to combine them into one result.
    /// This works in a similar manner to `Array.reduce<Result>(_:_:) -> Result`.
    ///
    /// Parameters:
    ///   - input: Input for request
    ///   - initialValue: The value to use as the initial accumulating value. `initialValue` is passed to `onPage` the first time it is called.
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each paginated response. It combines an accumulating result with the contents of response. This combined result is then returned
    ///         along with a boolean indicating if the paginate operation should continue.
    public func listTimelineEventsPaginator<Result>(
        _ input: ListTimelineEventsInput,
        _ initialValue: Result,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (Result, ListTimelineEventsOutput, EventLoop) -> EventLoopFuture<(Bool, Result)>
    ) -> EventLoopFuture<Result> {
        return self.client.paginate(
            input: input,
            initialValue: initialValue,
            command: self.listTimelineEvents,
            inputKey: \ListTimelineEventsInput.nextToken,
            outputKey: \ListTimelineEventsOutput.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }

    /// Provide paginated results to closure `onPage`.
    ///
    /// - Parameters:
    ///   - input: Input for request
    ///   - logger: Logger used flot logging
    ///   - eventLoop: EventLoop to run this process on
    ///   - onPage: closure called with each block of entries. Returns boolean indicating whether we should continue.
    public func listTimelineEventsPaginator(
        _ input: ListTimelineEventsInput,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil,
        onPage: @escaping (ListTimelineEventsOutput, EventLoop) -> EventLoopFuture<Bool>
    ) -> EventLoopFuture<Void> {
        return self.client.paginate(
            input: input,
            command: self.listTimelineEvents,
            inputKey: \ListTimelineEventsInput.nextToken,
            outputKey: \ListTimelineEventsOutput.nextToken,
            on: eventLoop,
            onPage: onPage
        )
    }
}

extension SSMIncidents.GetResourcePoliciesInput: AWSPaginateToken {
    public func usingPaginationToken(_ token: String) -> SSMIncidents.GetResourcePoliciesInput {
        return .init(
            maxResults: self.maxResults,
            nextToken: token,
            resourceArn: self.resourceArn
        )
    }
}

extension SSMIncidents.ListIncidentRecordsInput: AWSPaginateToken {
    public func usingPaginationToken(_ token: String) -> SSMIncidents.ListIncidentRecordsInput {
        return .init(
            filters: self.filters,
            maxResults: self.maxResults,
            nextToken: token
        )
    }
}

extension SSMIncidents.ListRelatedItemsInput: AWSPaginateToken {
    public func usingPaginationToken(_ token: String) -> SSMIncidents.ListRelatedItemsInput {
        return .init(
            incidentRecordArn: self.incidentRecordArn,
            maxResults: self.maxResults,
            nextToken: token
        )
    }
}

extension SSMIncidents.ListReplicationSetsInput: AWSPaginateToken {
    public func usingPaginationToken(_ token: String) -> SSMIncidents.ListReplicationSetsInput {
        return .init(
            maxResults: self.maxResults,
            nextToken: token
        )
    }
}

extension SSMIncidents.ListResponsePlansInput: AWSPaginateToken {
    public func usingPaginationToken(_ token: String) -> SSMIncidents.ListResponsePlansInput {
        return .init(
            maxResults: self.maxResults,
            nextToken: token
        )
    }
}

extension SSMIncidents.ListTimelineEventsInput: AWSPaginateToken {
    public func usingPaginationToken(_ token: String) -> SSMIncidents.ListTimelineEventsInput {
        return .init(
            filters: self.filters,
            incidentRecordArn: self.incidentRecordArn,
            maxResults: self.maxResults,
            nextToken: token,
            sortBy: self.sortBy,
            sortOrder: self.sortOrder
        )
    }
}

// MARK: Waiters

extension SSMIncidents {
    /// Wait for a replication set to become ACTIVE
    public func waitUntilWaitForReplicationSetActive(
        _ input: GetReplicationSetInput,
        maxWaitTime: TimeAmount? = nil,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil
    ) -> EventLoopFuture<Void> {
        let waiter = AWSClient.Waiter(
            acceptors: [
                .init(state: .success, matcher: try! JMESPathMatcher("replicationSet.status", expected: "ACTIVE")),
                .init(state: .retry, matcher: try! JMESPathMatcher("replicationSet.status", expected: "CREATING")),
                .init(state: .retry, matcher: try! JMESPathMatcher("replicationSet.status", expected: "UPDATING")),
                .init(state: .failure, matcher: try! JMESPathMatcher("replicationSet.status", expected: "FAILED")),
            ],
            minDelayTime: .seconds(30),
            maxDelayTime: .seconds(30),
            command: self.getReplicationSet
        )
        return self.client.waitUntil(input, waiter: waiter, maxWaitTime: maxWaitTime, logger: logger, on: eventLoop)
    }

    /// Wait for a replication set to be deleted
    public func waitUntilWaitForReplicationSetDeleted(
        _ input: GetReplicationSetInput,
        maxWaitTime: TimeAmount? = nil,
        logger: Logger = AWSClient.loggingDisabled,
        on eventLoop: EventLoop? = nil
    ) -> EventLoopFuture<Void> {
        let waiter = AWSClient.Waiter(
            acceptors: [
                .init(state: .success, matcher: AWSErrorCodeMatcher("ResourceNotFoundException")),
                .init(state: .retry, matcher: try! JMESPathMatcher("replicationSet.status", expected: "DELETING")),
                .init(state: .failure, matcher: try! JMESPathMatcher("replicationSet.status", expected: "FAILED")),
            ],
            minDelayTime: .seconds(30),
            maxDelayTime: .seconds(30),
            command: self.getReplicationSet
        )
        return self.client.waitUntil(input, waiter: waiter, maxWaitTime: maxWaitTime, logger: logger, on: eventLoop)
    }
}
